import { BTState } from "../BTState";
import { BTAbortType, hasAbortType } from "./BTAbortType";
import { BTComposite } from "./BTComposite";

/**
 * [行为树]选择节点
 * 按照子节点顺序依次执行子节点任务
 * 只要有一个子节点返回成功，选择节点将返回成功
 * 如果有一个子节点返回失败，选择节点将继续执行下一子节点
 * 若没有子节点返回成功，选择节点将返回失败
 */
export class BTSelector<T = any> extends BTComposite<T> {

    process(ctx: T): BTState {
        // 首先，如果我们不在第一个子节点身上，我们就处理条件性中止
        if (this.curIdx != 0) {
            this.handleConditionalAborts(ctx);
        }

        const child = this.children[this.curIdx];

        // 子节点执行任务成功或仍在运行中则返回子节点状态
        if (child.tick(ctx) !== BTState.fail) {
            this.curIdx = 0;
            return child.state;
        }

        if (++this.curIdx === this.children.length) {
            //没有子节点返回成功，代表选择节点执行失败了
            this.curIdx = 0;
            return BTState.fail;
        }

        return this.process(ctx);
    }

    private handleConditionalAborts(context: T) {
        // 检查任何较低优先级的任务，看它们是否改变为成功
        if (this._hasLowerPriorityConditionalAbort)
            this.updateLowerPriorityAbortConditional(context, BTState.fail);

        if (hasAbortType(this.abortType, BTAbortType.self))
            this.updateSelfAbortConditional(context, BTState.fail);
    }

}